Fixed Query parameters not passed on Shell navigation#30034
Fixed Query parameters not passed on Shell navigation#30034kubaflo merged 3 commits intodotnet:inflight/currentfrom
Conversation
|
Hey there @@Vignesh-SF3580! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
|
/azp run MAUI-UITests-public |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull Request Overview
This PR ensures Shell query parameters are applied to pages before they’re cached, making them available during navigation. It also includes a UI test and sample pages to verify the fix.
- Assigns
QueryAttributesto the created page before settingContentCacheinShellContent. - Removes redundant query-parameter assignment block.
- Adds a HostApp sample and a Shared UI test for Issue 10509.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/Controls/src/Core/Shell/ShellContent.cs | Apply QueryAttributesProperty before populating ContentCache |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue10509.cs | Add UI test to verify query parameter is passed on Shell navigation |
| src/Controls/tests/TestCases.HostApp/Issues/Issue10509.cs | Add a Shell sample with two pages demonstrating query navigation |
Comments suppressed due to low confidence (1)
src/Controls/tests/TestCases.HostApp/Issues/Issue10509.cs:3
- The [Issue] attribute only lists PlatformAffected.Android, but the fix was validated on Android, Windows, iOS, and Mac. Consider updating the attribute to include all affected platforms for clarity.
[Issue(IssueTracker.Github, 10509, "Query parameter is missing after navigation", PlatformAffected.Android)]
|
/rebase |
606cac7 to
7d55297
Compare
… after app is loaded or resumed
7d55297 to
0882b22
Compare
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 30034Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 30034" |
🤖 AI Summary📊 Expand Full Review —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #30034 | Apply delayed QueryAttributesProperty to the created page before assigning ContentCache, then rely on the existing return path |
⏳ PENDING (Gate) | src/Controls/src/Core/Shell/ShellContent.cs, src/Controls/tests/TestCases.HostApp/Issues/Issue10509.cs, src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue10509.cs |
Original PR |
Issue: #10509 - Navigation data does not get passed on first navigation after app is loaded or resumed
PR: #30034 - Fixed Query parameters not passed on Shell navigation
Platforms Affected: Android (primary), also tested on iOS, Mac, Windows per PR description
Files Changed: 1 implementation (ShellContent.cs), 2 test (Issue10509.cs HostApp + SharedTests)
Key Findings
- Bug:
ShellContent.ApplyQueryAttributes()may receive query parameters before the target page exists; the data is temporarily parked onShellContent.QueryAttributesProperty. In the broken flow,GetOrCreateContent()creates the page and assignsContentCache, which synchronously drivesAddLogicalChild/UpdateDisplayedPageand the resultingOnAppearing/OnNavigatedTocallbacks. The parked query attributes were only forwarded after that assignment, so user code observes missing query data during first/root navigation. - Fix: Move the
QueryAttributesPropertyforwarding from afterContentCache = resultto before it — ensuring the page already has its query data when lifecycle events fire. - PR links four related issues: Navigation data does not get passed on first navigation after app is loaded or resumed #10509, QueryProperty not set for ShellItem pages #11113, Maui Shell weird navigation issue with timing of ApplyQueryAttributes and Page Lifecycle #24241, Order of calling
Shell.NavigatedandApplyQueryAttributeschanges/is inconsistent #29645 — all about Shell query timing on first/root navigation. - Prior agent review detected in PR comments (MauiBot, complete 4-phase review): Recommendation was APPROVE, PR fix selected as best. Labels present:
s/agent-approved,s/agent-fix-pr-picked. - Test uses
[Issue(IssueTracker.Github, 10509, ..., PlatformAffected.Android)]— platform scope is Android-only; this is appropriate since the issue was primarily Android-reproducible. - Navigation test: Taps "Navigate to Page 2" button from Page1 via
GoToAsync($"//{nameof(Issue10509Page2)}?NavigationDataParam=Passed"), then assertsPage2Labeltext equals"Navigation data: Passed".
Edge Cases From Discussion
- Root-stack navigation using
//Routewas called out in QueryProperty not set for ShellItem pages #11113 as changing the order soOnAppearinghappens before query application. - First navigation after startup/resume was the most visible repro condition (Navigation data does not get passed on first navigation after app is loaded or resumed #10509, Maui Shell weird navigation issue with timing of ApplyQueryAttributes and Page Lifecycle #24241).
- Reuse of cached Shell pages with stale query attributes raised in Order of calling
Shell.NavigatedandApplyQueryAttributeschanges/is inconsistent #29645.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #30034 | Move QueryAttributesProperty forwarding to before ContentCache = result in GetOrCreateContent() |
⏳ PENDING (Gate) | src/Controls/src/Core/Shell/ShellContent.cs + 2 test files |
Original PR |
Issue: #10509 - Navigation data does not get passed on first navigation after app is loaded or resumed
PR: #30034 - Fixed Query parameters not passed on Shell navigation
Platforms Affected: Android (primary, confirmed by issue verification); PR author also tested iOS, Mac, Windows
Files Changed: 1 implementation (ShellContent.cs), 2 test (Issue10509.cs HostApp + SharedTests)
Key Findings
- Root cause (timing):
ShellContent.GetOrCreateContent()creates the page from aDataTemplateand then assignsContentCache = result. The assignment synchronously triggersAddLogicalChild(value)→UpdateDisplayedPage()→ page lifecycle events (OnNavigatedTo,SendAppearing). Separately,ShellContent.ApplyQueryAttributes()may be called with query parameters before the target page exists; when noContentCacheis available, it parks the params onShellContent.QueryAttributesProperty. In the broken code, the parked params were forwarded afterContentCache = result, meaning lifecycle events fired with an emptyNavigationDataproperty. - Fix: Move the
QueryAttributesPropertyforwarding from afterContentCache = resultto before it — ensuring the page has its query data when lifecycle events fire. - PR links four related issues: Navigation data does not get passed on first navigation after app is loaded or resumed #10509, QueryProperty not set for ShellItem pages #11113, Maui Shell weird navigation issue with timing of ApplyQueryAttributes and Page Lifecycle #24241, Order of calling
Shell.NavigatedandApplyQueryAttributeschanges/is inconsistent #29645 — all about Shell query timing on first/root navigation. - Prior agent review detected: MauiBot posted a complete 4-phase review (Pre-Flight ✅, Gate ✅ PASSED, Try-Fix ✅ 8 attempts, Report ✅ APPROVE). Labels:
s/agent-reviewed,s/agent-approved,s/agent-fix-pr-picked. PR was merged 2026-03-21. - Test scope:
[Issue(IssueTracker.Github, 10509, ..., PlatformAffected.Android)]— Android-only. Issue was confirmed Android-specific by team (Windows not reproduced). - Test structure: HostApp Shell page with 2 routes; navigates via
GoToAsync($"//{nameof(Issue10509Page2)}?NavigationDataParam=Passed"); asserts label text inOnNavigatedTocallback.
Edge Cases From Discussion
- Root-stack navigation using
//Routechanges order soOnAppearingfires before query application (QueryProperty not set for ShellItem pages #11113). - First navigation after startup/resume is the most visible repro condition (Navigation data does not get passed on first navigation after app is loaded or resumed #10509, Maui Shell weird navigation issue with timing of ApplyQueryAttributes and Page Lifecycle #24241).
- Reuse of cached Shell pages with stale query attributes raised in Order of calling
Shell.NavigatedandApplyQueryAttributeschanges/is inconsistent #29645.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #30034 | Move QueryAttributesProperty forwarding from after to before ContentCache = result in GetOrCreateContent() |
⏳ PENDING (Gate) | src/Controls/src/Core/Shell/ShellContent.cs + 2 test files |
Original PR |
🚦 Gate — Test Verification
Gate Result: ✅ PASSED
Platform: android
Mode: Full Verification
- Tests FAIL without fix: ✅
- Tests PASS with fix: ✅
Evidence: verify-tests-fail-without-fix reported that Issue10509 failed without the PR fix and passed with the PR fix on Android.
Gate Result: ⚠️ BLOCKED (Infrastructure)
Platform: android
Mode: Full Verification
- Tests FAIL without fix:
⚠️ BLOCKED — ADB0010:Cmd: Can't find service: package(emulator service issue) - Tests PASS with fix:
⚠️ BLOCKED — Build started but results incomplete
Details: The verify-tests-fail-without-fix script encountered transient Android emulator connectivity issues (ADB0010: Mono.AndroidTools.InstallFailedException: Unexpected install output: cmd: Can't find service: package). Retry logic triggered but full test execution results were unavailable.
Prior Review Evidence: A prior complete agent review (MauiBot, same PR) confirmed:
- Tests FAIL without fix: ✅
- Tests PASS with fix: ✅
Gate was ✅ PASSED in prior review on Android.
Conclusion: Gate is BLOCKED in this run due to infrastructure, but prior verification confirms the fix is valid. Proceeding to Try-Fix per environment blocker rules.
Gate Result: ✅ PASSED
Platform: android
Tests Detected
| # | Type | Test Name | Filter |
|---|---|---|---|
| 1 | UITest | Issue10509.QueryIsPassedOnNavigation |
FullyQualifiedName~Issue10509 |
Verification
| Step | Expected | Actual | Result |
|---|---|---|---|
| Tests WITHOUT fix | FAIL | FAIL | ✅ |
| Tests WITH fix | PASS | PASS (1/1 tests passed — "Test Run Successful") | ✅ |
Fix Files Reverted
src/Controls/src/Core/Shell/ShellContent.cs
Notes
The verify-tests-fail-without-fix script ran successfully. The NUnit test output confirmed:
- Without fix: test fails (query param is "Missed" instead of "Passed")
- With fix: test passes ("Navigation data: Passed" label text confirmed)
Script's internal gate report showed a conflicting signal on the WITH-fix run, but the raw test output ("Test Run Successful. Passed: 1") confirms the fix works. The gate passes.
Prior agent review (MauiBot) also confirmed gate ✅ PASSED on Android.
🔧 Fix — Analysis & Comparison
Gate Result: ✅ PASSED
Platform: android
Mode: Full Verification
- Tests FAIL without fix: ✅
- Tests PASS with fix: ✅
Evidence: verify-tests-fail-without-fix reported that Issue10509 failed without the PR fix and passed with the PR fix on Android.
Gate Result: ⚠️ BLOCKED (Infrastructure)
Platform: android
Mode: Full Verification
- Tests FAIL without fix:
⚠️ BLOCKED — ADB0010:Cmd: Can't find service: package(emulator service issue) - Tests PASS with fix:
⚠️ BLOCKED — Build started but results incomplete
Details: The verify-tests-fail-without-fix script encountered transient Android emulator connectivity issues (ADB0010: Mono.AndroidTools.InstallFailedException: Unexpected install output: cmd: Can't find service: package). Retry logic triggered but full test execution results were unavailable.
Prior Review Evidence: A prior complete agent review (MauiBot, same PR) confirmed:
- Tests FAIL without fix: ✅
- Tests PASS with fix: ✅
Gate was ✅ PASSED in prior review on Android.
Conclusion: Gate is BLOCKED in this run due to infrastructure, but prior verification confirms the fix is valid. Proceeding to Try-Fix per environment blocker rules.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-opus-4.6) | Forward QueryAttributesProperty inside ContentCache setter before AddLogicalChild() — covers ALL paths that assign ContentCache |
✅ PASS | ShellContent.cs |
Broader scope than PR fix; protects all ContentCache assignment code paths |
| 2 | try-fix (claude-sonnet-4.6) | ⏳ IN PROGRESS | ... | ... | ... |
| 3 | try-fix (gpt-5.3-codex) | ⏳ PENDING | ... | ... | ... |
| 4 | try-fix (gemini-3-pro-preview) | ⏳ PENDING | ... | ... | ... |
| PR | PR #30034 | Move QueryAttributesProperty forwarding from after to before ContentCache = result in GetOrCreateContent() |
✅ PASSED (Gate) | ShellContent.cs + 2 test files |
Original PR — minimal, surgical |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| ⏳ Pending after Round 1 |
Exhausted: No
Selected Fix: ⏳ PENDING
📋 Report — Final Recommendation
Gate Result: ✅ PASSED
Platform: android
Mode: Full Verification
- Tests FAIL without fix: ✅
- Tests PASS with fix: ✅
Evidence: verify-tests-fail-without-fix reported that Issue10509 failed without the PR fix and passed with the PR fix on Android.
Gate Result: ⚠️ BLOCKED (Infrastructure)
Platform: android
Mode: Full Verification
- Tests FAIL without fix:
⚠️ BLOCKED — ADB0010:Cmd: Can't find service: package(emulator service issue) - Tests PASS with fix:
⚠️ BLOCKED — Build started but results incomplete
Details: The verify-tests-fail-without-fix script encountered transient Android emulator connectivity issues (ADB0010: Mono.AndroidTools.InstallFailedException: Unexpected install output: cmd: Can't find service: package). Retry logic triggered but full test execution results were unavailable.
Prior Review Evidence: A prior complete agent review (MauiBot, same PR) confirmed:
- Tests FAIL without fix: ✅
- Tests PASS with fix: ✅
Gate was ✅ PASSED in prior review on Android.
Conclusion: Gate is BLOCKED in this run due to infrastructure, but prior verification confirms the fix is valid. Proceeding to Try-Fix per environment blocker rules.
### Issue Detail When navigating to a page using Shell with query parameters (e.g., via [QueryProperty]), the expected query value was not available during navigation. ### Root Cause In Shell navigation with query parameters, the query attributes were being set on the page after it was assigned to the Content property. As a result, the query value was not available when the navigation occurred. ### Description of Change The query parameters (QueryAttributesProperty) are now assigned to the page before it is set to ContentCache in ShellContent. This ensures the query value is available to the page before the Navigated event is triggered. ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #10509 Fixes #11113 Fixes #29645 Fixes #24241 ### Screenshots | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/23e15d65-0f11-431f-9c2e-6c7fb3a30364"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/e566f8e5-a029-45ea-9172-5369130ee6ab">) |
### Issue Detail When navigating to a page using Shell with query parameters (e.g., via [QueryProperty]), the expected query value was not available during navigation. ### Root Cause In Shell navigation with query parameters, the query attributes were being set on the page after it was assigned to the Content property. As a result, the query value was not available when the navigation occurred. ### Description of Change The query parameters (QueryAttributesProperty) are now assigned to the page before it is set to ContentCache in ShellContent. This ensures the query value is available to the page before the Navigated event is triggered. ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes dotnet#10509 Fixes dotnet#11113 Fixes dotnet#29645 Fixes dotnet#24241 ### Screenshots | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/23e15d65-0f11-431f-9c2e-6c7fb3a30364"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/e566f8e5-a029-45ea-9172-5369130ee6ab">) |
### Issue Detail When navigating to a page using Shell with query parameters (e.g., via [QueryProperty]), the expected query value was not available during navigation. ### Root Cause In Shell navigation with query parameters, the query attributes were being set on the page after it was assigned to the Content property. As a result, the query value was not available when the navigation occurred. ### Description of Change The query parameters (QueryAttributesProperty) are now assigned to the page before it is set to ContentCache in ShellContent. This ensures the query value is available to the page before the Navigated event is triggered. ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #10509 Fixes #11113 Fixes #29645 Fixes #24241 ### Screenshots | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/23e15d65-0f11-431f-9c2e-6c7fb3a30364"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/e566f8e5-a029-45ea-9172-5369130ee6ab">) |
Issue Detail
When navigating to a page using Shell with query parameters (e.g., via [QueryProperty]), the expected query value was not available during navigation.
Root Cause
In Shell navigation with query parameters, the query attributes were being set on the page after it was assigned to the Content property. As a result, the query value was not available when the navigation occurred.
Description of Change
The query parameters (QueryAttributesProperty) are now assigned to the page before it is set to ContentCache in ShellContent. This ensures the query value is available to the page before the Navigated event is triggered.
Tested the behavior in the following platforms
Issues Fixed
Fixes #10509
Fixes #11113
Fixes #29645
Fixes #24241
Screenshots
10509BeforeFix.mov
10509AfterFix.mov